package com.piggy.im.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.piggy.common.core.constant.BizConstants;
import com.piggy.common.core.exception.base.BaseException;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.common.datascope.annotation.DataScope;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.im.domain.SysStationMessage;
import com.piggy.im.domain.bo.SysStationMessageAddBo;
import com.piggy.im.domain.bo.SysStationMessageEditBo;
import com.piggy.im.domain.bo.SysStationMessageQueryBo;
import com.piggy.im.domain.vo.SysStationMessageVo;
import com.piggy.im.server.domain.SysStationMessageMark;
import com.piggy.im.server.enums.MarkEnum;
import com.piggy.im.server.mapper.SysStationMessageMapper;
import com.piggy.im.server.mapper.SysStationMessageMarkMapper;
import com.piggy.im.server.service.ISysStationMessageService;
import com.piggy.logi.common.datascope.annotation.LogiDataScope;
import com.piggy.logi.sys.api.domain.LogiSysRole;
import com.piggy.logi.sys.api.domain.LogiSysUser;
import com.piggy.sys.api.domain.SysRole;
import com.piggy.sys.api.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 站内消息Service业务层处理
 *
 * @author piggy
 * @date 2021-12-09
 */
@Service
public class SysStationMessageServiceImpl extends ServiceImpl<SysStationMessageMapper, SysStationMessage> implements ISysStationMessageService {

    @Autowired
    private SysStationMessageMarkMapper markMapper;

    @Override
    public SysStationMessageVo queryById(Long id) {
        List<SysStationMessageVo> voList = baseMapper.selectMsgList(buildQueryWrapper(new SysStationMessageQueryBo().setId(id)), SecurityUtils.getUserId());
        if (CollUtil.isNotEmpty(voList)) {
            return voList.get(0);
        }
        return null;
    }

    @Override
    public TableDataInfo<SysStationMessageVo> queryPageList(SysStationMessageQueryBo bo) {
        if (ObjectUtil.isEmpty(bo.getMainDeptId())) {
            bo.setMainDeptId(SecurityUtils.getMainDeptId());
        }
        if (ObjectUtil.isEmpty(bo.getReceiveId())) {
            Long userId = SecurityUtils.getUserId();
            bo.setReceiveId(userId);
        }
        PageInfo<SysStationMessageVo> result = startPage(bo).doSelectPageInfo(() -> {
            List<SysStationMessageVo> voList = baseMapper.selectMsgList(buildQueryWrapper(bo), SecurityUtils.getUserId());
        });
        return PageUtils.buildDataInfo(result);
    }

    @Override
    //@LogiDataScope(deptAlias="d")
    public List<SysStationMessageVo> queryList(SysStationMessageQueryBo bo) {
        return baseMapper.selectMsgList(buildQueryWrapper(bo), SecurityUtils.getUserId());
    }

    private QueryWrapper<SysStationMessage> buildQueryWrapper(SysStationMessageQueryBo bo) {
        QueryWrapper<SysStationMessage> lqw = Wrappers.query();
        lqw.eq(Objects.nonNull(bo.getId()), "msg.id", bo.getId());
        lqw.eq(StrUtil.isNotBlank(bo.getLevel()), "msg.level", bo.getLevel());
        lqw.eq(StrUtil.isNotBlank(bo.getTitle()), "msg.title", bo.getTitle());
        lqw.eq(StrUtil.isNotBlank(bo.getContent()), "msg.content", bo.getContent());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getMark()), "mark.mark", bo.getMark());
        //lqw.eq(ObjectUtil.isNotEmpty(bo.getReceiveId()), SysStationMessage::getReceiveId, bo.getReceiveId());
        //lqw.eq(ObjectUtil.isNotEmpty(bo.getDeptId()), SysStationMessage::getDeptId, bo.getDeptId());
        //lqw.eq(ObjectUtil.isNotEmpty(bo.getRoleId()), SysStationMessage::getRoleId, bo.getRoleId());
        lqw.in(ObjectUtil.isNotEmpty(bo.getMsgType()), "msg.msg_type", bo.getMsgType());
        lqw.eq("msg.biz_sys", SecurityUtils.getOauthUser().getBiz());

        Long deptId = SecurityUtils.getDeptId();
        List<Long> roleIds = new ArrayList<>();
        if (SecurityUtils.getOauthUser().getBiz().equals(BizConstants.BOSS)) {
            List<SysRole> roles = ((SysUser) SecurityUtils.getOauthUser().getSysUser()).getRoles();
            if (CollUtil.isEmpty(roles)) {
                roles = Lists.newArrayList(new SysRole().setRoleId(0L).setFlag(true));
            }
            //获取当前用户未读消息个数
            roleIds = roles.stream().map(t-> {
                if (t.isFlag()) {
                    return t.getRoleId();
                }
                return 0L;
            }).distinct().collect(Collectors.toList());
        }
        if (SecurityUtils.getOauthUser().getBiz().equals(BizConstants.LOGI)) {
            List<LogiSysRole> roles = ((LogiSysUser) SecurityUtils.getOauthUser().getSysUser()).getRoles();
            if (CollUtil.isEmpty(roles)) {
                roles = Lists.newArrayList(new LogiSysRole().setRoleId(0L).setFlag(true));
            }
            //获取当前用户未读消息个数
            roleIds = roles.stream().map(t-> {
                if (t.isFlag()) {
                    return t.getRoleId();
                }
                return 0L;
            }).distinct().collect(Collectors.toList());
        }

        //获取当前用户未读消息个数
        List<Long> finalRoleIds = roleIds.stream().distinct().collect(Collectors.toList());
        lqw.and(i -> i.eq("msg.receive_id", SecurityUtils.getUserId()).or(CollUtil.isNotEmpty(finalRoleIds)).in("msg.role_id", finalRoleIds).or().eq("msg.dept_id", deptId).or().eq("msg.receive_id", -1L));
        lqw.orderByDesc("msg.create_time");
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(SysStationMessageAddBo bo) {
        SysStationMessage add = BeanUtil.toBean(bo, SysStationMessage.class);
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(SysStationMessageEditBo bo) {
        SysStationMessage update = BeanUtil.toBean(bo, SysStationMessage.class);
        return updateById(update);
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    @Override
    public Boolean haveRead(Collection<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new BaseException("未读id列表不能为空");
        }

        List<SysStationMessageMark> updateList = ids.stream().map(item -> {
            SysStationMessageMark add = new SysStationMessageMark();
            add.setMessageId(item);
            add.setMark(MarkEnum.HAVE_READ.getType());
            add.setUserId(SecurityUtils.getUserId());
            return add;
        }).collect(Collectors.toList());
        return markMapper.insertBatch(updateList);
    }

    @Override
    public Integer unreadCount() {
        Long userId = SecurityUtils.getUserId();
        Long deptId = SecurityUtils.getDeptId();
        List<Long> roleIds = new ArrayList<>();
        if (SecurityUtils.getOauthUser().getSysUser() instanceof SysUser) {
            List<SysRole> roles = ((SysUser) SecurityUtils.getOauthUser().getSysUser()).getRoles();
            if (CollUtil.isEmpty(roles)) {
                roles = Lists.newArrayList(new SysRole().setRoleId(0L).setFlag(true));
            }
            //获取当前用户未读消息个数
            roleIds = roles.stream().map(t-> {
                if (t.isFlag()) {
                    return t.getRoleId();
                }
                return 0L;
            }).distinct().collect(Collectors.toList());
        }
        if (SecurityUtils.getOauthUser().getSysUser() instanceof LogiSysUser) {
            List<LogiSysRole> roles = ((LogiSysUser) SecurityUtils.getOauthUser().getSysUser()).getRoles();
            if (CollUtil.isEmpty(roles)) {
                roles = Lists.newArrayList(new LogiSysRole().setRoleId(0L).setFlag(true));
            }
            //获取当前用户未读消息个数
            roleIds = roles.stream().map(t-> {
                if (t.isFlag()) {
                    return t.getRoleId();
                }
                return 0L;
            }).distinct().collect(Collectors.toList());
        }

        //获取当前用户未读消息个数
        List<Long> finalRoleIds = roleIds.stream().distinct().collect(Collectors.toList());

        long count = baseMapper.selectUnRead(new QueryWrapper<SysStationMessage>()
                .eq("msg.biz_sys", SecurityUtils.getOauthUser().getBiz())
                .and(i -> i.eq("msg.receive_id", userId).or(CollUtil.isNotEmpty(finalRoleIds)).in("msg.role_id", finalRoleIds).or().eq("msg.dept_id", deptId).or().eq("msg.receive_id", -1L)), SecurityUtils.getUserId());
        return (int) count;
    }
}
